package com.ldzl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ldzl.dto.AddPurchaseOrderDTO;
import com.ldzl.dto.ArrivalNoticeDTO;
import com.ldzl.dto.ArrivalStorageRequestDTO;
import com.ldzl.pojo.*;
import com.ldzl.service.*;
import com.ldzl.mapper.CkPurchaseOrderMapper;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.api.BasicService;
import com.ruoyi.system.api.domain.BasicWlgl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 风止
* @description 针对表【ck_purchase_order(采购订单表)】的数据库操作Service实现
* @createDate 2025-07-11 11:17:44
*/
@Service
@Transactional
public class CkPurchaseOrderServiceImpl extends ServiceImpl<CkPurchaseOrderMapper, CkPurchaseOrder>
    implements CkPurchaseOrderService{

    @Autowired
    private CkPurchaseOrderLineService pols; // 采购订单详情

    @Autowired
    private BasicService bs; //基础数据 外部服务

    @Autowired
    private CkBatchService batch; //批次
    @Autowired
    private ScPurchaseRequisitionService prs; //采购申请

    @Autowired
    private CkItemRecptService irs; //入库单服务

    /**
     * 查询采购订单
     * @param po
     * @return
     */
    @Override
    public List<CkPurchaseOrder> findOrder(CkPurchaseOrder po) {
        return super.baseMapper.selectOrder(po);
    }

    /**
     * 创建采购订单
     * @param orderDTO
     * @return
     */
    @Override
    public boolean addOrder(AddPurchaseOrderDTO orderDTO) {
        Date date = new Date(); //获取当前时间
        CkPurchaseOrder order = orderDTO.getOrder(); //采购订单
        //判断是否为修改
        boolean isUpdate = order.getPo_id() != null;

        List<CkPurchaseOrderLine> listOrderLine = orderDTO.getListOrderLine(); //采购商品列表

        //1.创建批次信息
        AjaxResult ajaxResult = bs.automaticallyNumbers(28L); //生成批次编码 28为批次编码
        CkBatch bat = new CkBatch();
        bat.setBatch_code(order.getBatch_code());
        bat.setProduce_date(date);
        // 获取当前日期
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, 3);// 加三年
        Date threeYearsLater = calendar.getTime();
        bat.setExpire_date(threeYearsLater);
        bat.setSupplier_id(order.getSupplier_id());
        bat.setSupplier_name(order.getSupplier_name());

        //2.创建采购订单
        order.setBatch_code(bat.getBatch_code());
        order.setPurchase_date(date);
        //order.setStatus("1");
        //计算总金额
        BigDecimal totalPrice = orderDTO.getListOrderLine().stream().map(line -> line.getTotal_price()).reduce(BigDecimal.ZERO, BigDecimal::add);
        order.setTotal_amount(totalPrice);
        order.setCreate_time(date);
        order.setUpdate_time(date);
        order.setIs_delete("0");

        //保存采购订单
        if(super.saveOrUpdate(order)){
            //继续保存批次信息、 剩下的采购订单信息
            bat.setPo_id(order.getPo_id());
            bat.setPo_code(order.getPo_code());
            bat.setPo_name(order.getPo_name());
            bat.setCreate_by(order.getCreate_by());
            bat.setCreate_time(date);
            bat.setUpdate_by(order.getUpdate_by());
            bat.setUpdate_time(date);

            //3.创建采购订单行
            listOrderLine.forEach(line -> {
                line.setPo_id(order.getPo_id());
                line.setWait_num(line.getQuantity_num());
                line.setArrived_num(new BigDecimal(0));
                line.setStatus("1"); //默认运输中
                line.setCreate_by(order.getCreate_by());
                line.setCreate_time(date);
                line.setUpdate_by(order.getUpdate_by());
                line.setUpdate_time(date);
                line.setIs_delete("0");

                //扣减采购类型为生产采购的采购申请表中的采购数量
                if(order.getPurchase_type().equals("生产采购")){
                    ScPurchaseRequisition pr = prs.getOne( new QueryWrapper<ScPurchaseRequisition>()
                            .eq("product_name", line.getGoods_name())
                            .eq("is_delete", 0)
                    );
                    ScPurchaseRequisition requisition= new ScPurchaseRequisition();
                    requisition.setRequisition_id(pr.getRequisition_id());
                    requisition.setRequired_quantity(pr.getRequired_quantity().subtract(line.getQuantity_num()));
                    requisition.setUpdate_by(order.getUpdate_by());
                    requisition.setUpdate_time(date);
                    if(pr.getRequired_quantity().compareTo(BigDecimal.ZERO) > 0){
                        if(!prs.saveOrUpdate(requisition))
                            System.out.println("修改采购申请表数量失败："+line.getGoods_name());
                    }
                }
            });
            //修改采购订单时查找 被移除的采购商品
            if(isUpdate){
                List<CkPurchaseOrderLine> listLine = pols.selectOrderLine_id(order.getPo_id());
                //获取被删除的采购商品
                //List<CkPurchaseOrderLine> deleteLine = new ArrayList<>(listOrderLine);
                //deleteLine.removeAll(listLine);
                /*listLine.removeAll(listOrderLine);
                listLine.forEach( line -> {
                    System.out.println("测试移除的采购商品："+line.getGoods_name());
                    try {
                        pols.updateIs_delete(line.getLine_id());
                    } catch (Exception e) {
                        // 记录异常信息
                        System.err.println("移除失败，line_id: " + line.getLine_id() + "，错误信息：" + e.getMessage());
                    }
                });*/

                listOrderLine.forEach(line -> {
                    listLine.removeIf(line2 -> isSameLineId(line.getLine_id(), line2.getLine_id()));
                });
                //移除采购订单行
                listLine.forEach( line -> {
                    //为移除采购的商品修改回采购数量
                    if(order.getPurchase_type().equals("生产采购")){
                        ScPurchaseRequisition pr = prs.getOne( new QueryWrapper<ScPurchaseRequisition>()
                                .eq("product_name", line.getGoods_name())
                                .eq("is_delete", 0)
                        );
                        ScPurchaseRequisition requisition= new ScPurchaseRequisition();
                        requisition.setRequisition_id(pr.getRequisition_id());
                        requisition.setRequired_quantity(pr.getRequired_quantity().add(line.getQuantity_num()));
                        requisition.setUpdate_by(order.getUpdate_by());
                        requisition.setUpdate_time(date);
                        if(!prs.saveOrUpdate(requisition))
                            System.out.println("修改回采购申请表数量失败："+line.getGoods_name());
                    }
                    pols.updateIs_delete(line.getLine_id());
                });
            }

            //只有新增才保存批次
            if(!isUpdate){
                batch.save(bat); //保存批次
            }
            return pols.saveOrUpdateBatch(listOrderLine); //批量保存采购订单行
        }

        //只有新增才保存批次
        if(!isUpdate){
            batch.insertBatch(bat); //保存批次
        }
        return false;
    }

    /**
     * 判断两个采购订单行是否相同
     * @param line1
     * @param line2
     * @return
     */
    private boolean isSameLineId(Long line1, Long line2) {
        return line1 != null && line2 != null && line1.equals(line2);
    }

    /**
     * 移除采购订单
     * @param po_id
     * @return
     */
    @Override
    public int updateIs_delete(Long po_id) {
        Date date = new Date();

        //查询本次要删除的采购订单信息
        CkPurchaseOrder order = super.getOne(new QueryWrapper<CkPurchaseOrder>()
                .eq("po_id", po_id)
                .eq("is_delete", 0)
        );
        //判断是否属于生产采购 为移除采购的商品修改回采购数量
        if(order.getPurchase_type().equals("生产采购")){
            //获取订单下的商品信息
            List<CkPurchaseOrderLine> listOrderLine = pols.selectOrderLine_id(po_id);
            listOrderLine.forEach(line -> {
                ScPurchaseRequisition pr = prs.getOne( new QueryWrapper<ScPurchaseRequisition>()
                        .eq("product_name", line.getGoods_name())
                        .eq("is_delete", 0)
                );
                ScPurchaseRequisition requisition= new ScPurchaseRequisition();
                requisition.setRequisition_id(pr.getRequisition_id());
                requisition.setRequired_quantity(pr.getRequired_quantity().add(line.getQuantity_num()));
                requisition.setUpdate_by(order.getUpdate_by());
                requisition.setUpdate_time(date);

                if(!prs.saveOrUpdate(requisition))
                    System.out.println("删除采购订单时回滚采购申请表数量失败："+line.getGoods_name());
            });
        }

        if(pols.updateIs_delete_line(po_id)){
            if(super.baseMapper.updateIs_delete(po_id) > 0)
                return 1; //采购单删除成功
            else
                return 2; //采购单删除失败
        }
        return 2; //采购商品删除失败
    }

    /**
     * 批量移除采购订单
     * @param list_po_id
     * @return
     */
    @Override
    public int updateIs_delete_batch(List<Long> list_po_id) {
        Date date = new Date(); //获取当前时间
        List<CkPurchaseOrder> listOrder = new ArrayList<>(); //要移除的采购订单集合
        for (Long po_id : list_po_id) {
            //查询本次要删除的采购订单信息
            CkPurchaseOrder order = super.getOne(new QueryWrapper<CkPurchaseOrder>()
                    .eq("po_id", po_id)
                    .eq("is_delete", 0)
            );
            //判断是否属于生产采购 为移除采购的商品修改回采购数量
            if(order.getPurchase_type().equals("生产采购")){
                //获取订单下的商品信息
                List<CkPurchaseOrderLine> listOrderLine = pols.selectOrderLine_id(po_id);
                listOrderLine.forEach(line -> {
                    ScPurchaseRequisition pr = prs.getOne( new QueryWrapper<ScPurchaseRequisition>()
                            .eq("product_name", line.getGoods_name())
                            .eq("is_delete", 0)
                    );
                    ScPurchaseRequisition requisition= new ScPurchaseRequisition();
                    requisition.setRequisition_id(pr.getRequisition_id());
                    requisition.setRequired_quantity(pr.getRequired_quantity().add(line.getQuantity_num()));
                    requisition.setUpdate_by(order.getUpdate_by());
                    requisition.setUpdate_time(date);

                    if(!prs.saveOrUpdate(requisition))
                        System.out.println("删除采购订单时回滚采购申请表数量失败："+line.getGoods_name());
                });
            }

            CkPurchaseOrder po = new CkPurchaseOrder();
            po.setPo_id(po_id);
            po.setIs_delete("1");

            //移除当前采购订单下的 采购订单行
            pols.updateIs_delete_line(po_id);
            listOrder.add(po);
        }
        if(!super.updateBatchById(listOrder))
            return 2;
        return 1;
    }

    /**
     * 提交采购订单
     * @param po_id
     * @return
     */
    @Override
    public boolean updateStatus(Long po_id) {
        CkPurchaseOrder po = new CkPurchaseOrder();
        po.setPo_id(po_id);
        po.setStatus("2");
        return super.updateById( po);
    }

    /**
     * 查询采购订单已到货和采购中的订单
     * @param po
     * @return
     */
    @Override
    public List<CkPurchaseOrder> findOrder_arrived(CkPurchaseOrder po) {
        return super.baseMapper.selectOrder_arrived(po);
    }

    /**
     * 到货入库
     * @param arrivalStorageDto
     * @return
     */
    @Override
    public boolean arrivalStorage(ArrivalStorageRequestDTO arrivalStorageDto) {
        boolean isSuccess = true; // 默认成功
        //获取要入库的商品
        List<ArrivalNoticeDTO> ListArrDto = arrivalStorageDto.getArrDto();
        //获取修改人
        String update_by = arrivalStorageDto.getUpdate_by();
        //获取采购订单id 去重后
        Set<Long> po_ids = new LinkedHashSet<>();
        //遍历发送的入库商品
        for (ArrivalNoticeDTO dto : ListArrDto) {
            if(pols.updateArrivalStorage(dto.getLine_id(),dto.getDelivery_num()) <= 0){
                System.out.println("修改入库数量失败:"+dto.getGoods_name());
                isSuccess = false; //到货入库失败
            }
            //更新商品详情的更新人和更新时间
            CkPurchaseOrderLine line = new CkPurchaseOrderLine();
            line.setLine_id(dto.getLine_id());
            line.setUpdate_by(update_by);
            line.setUpdate_time(new Date());
            if(!pols.saveOrUpdate(line)){
                System.out.println("更新商品详情失败:"+dto.getLine_id());
                isSuccess = false;
            }

            po_ids.add(dto.getPo_id());
        }

        //查找采购订单下的待到货数量是否 小于等于0，小于就修改状态为到货
        for (Long po_id : po_ids) {
            if(pols.waitNumSum(po_id).compareTo(BigDecimal.ZERO) <= 0){
                //修改状态为到货
                CkPurchaseOrder po = new CkPurchaseOrder();
                po.setPo_id(po_id);
                po.setUpdate_by(update_by);
                po.setUpdate_time(new Date());
                po.setStatus("3"); //到货
                if(!super.saveOrUpdate(po)){
                    System.out.println("修改采购订单状态失败："+po_id);
                    isSuccess = false; //到货入库失败
                }

            }
        }
        return isSuccess;
    }

}




